001    /**
002     * Created by IntelliJ IDEA.
003     * User: Wei Wang
004     * Date: Apr 16, 2003
005     * Time: 9:56:12 PM
006     */
007    
008    package EVolve.util.phasedetectors;
009    
010    import EVolve.util.equators.*;
011    import EVolve.util.settings.PhaseDetectorSetting;
012    import EVolve.util.phasedetectors.phasedetectorUI.PhaseDetectorToolBarState;
013    import EVolve.Scene;
014    import javax.swing.*;
015    import java.util.*;
016    import java.awt.*;
017    
018    public class HotspotPhaseDetector extends PhaseDetector{
019        private UnorderedUnlimitedSet previous, current;
020        private final byte graduateChange = 0x0000, notChange = 0x0001;
021        private byte status[];
022        private int noiseTolerance, sampleSize, targetSize;
023        private float threshold;
024        private final String configName = "hotspot_detector";
025    
026        private ArrayList samplePhase;
027        private UnorderedUnlimitedSet workingSet;
028    
029        private JTextField[] contents;
030        private String[] tags;
031    
032        public HotspotPhaseDetector() {
033            super();
034            workingSet = new UnorderedUnlimitedSet();
035            data.add(workingSet);
036    
037            threshold = (float)0.8;
038            noiseTolerance = 2;
039            targetSize = sampleSize = 1;
040    
041            samplePhase = new ArrayList();
042    
043            tags = new String[4];
044            tags[0] = "[Noise tolerance (intervals)]";
045            tags[1] = "[Threshold]";
046            tags[2] = "[Sample]";
047            tags[3] = "[Target]";
048    
049            JTextField textUpperThreshold, textNoiseTolerance;
050            JTextField textSampleSize, textTargetSize;
051            contents = new JTextField[4];
052            contents[0] = textNoiseTolerance = new JTextField();
053            contents[0].setColumns(2);
054    
055            contents[1] = textUpperThreshold = new JTextField();
056            contents[1].setColumns(3);
057    
058            contents[2] = textSampleSize = new JTextField();
059            contents[2].setColumns(2);
060    
061            contents[3] = textTargetSize = new JTextField();
062            contents[3].setColumns(2);
063    
064            textUpperThreshold.setText(String.valueOf(threshold));
065            textUpperThreshold.setToolTipText("Match threshold, from 0-1");
066            textSampleSize.setText(String.valueOf(sampleSize));
067            textSampleSize.setToolTipText("Take how many previous intervals as a sample set");
068            textTargetSize.setText(String.valueOf(targetSize));
069            textTargetSize.setToolTipText("Take how many intervals as a target set");
070            textNoiseTolerance.setText(String.valueOf(noiseTolerance));
071            textNoiseTolerance.setToolTipText("Noise tolerance");
072            refreshDetectorParameters();
073        }
074    
075        public void reset() {
076            super.reset();
077            workingSet = new UnorderedUnlimitedSet();
078            data.add(workingSet);
079            samplePhase.clear();
080        }
081    
082        public String getName() {
083            return "Hotspot Detector";
084        }
085    
086        protected void refreshDetectorParameters() {
087            PhaseDetectorSetting setting = PhaseDetectorSetting.v();
088            setting.readDataFromFile(tags, contents, configName);
089            try {
090                noiseTolerance = Integer.parseInt(contents[0].getText());
091                threshold = Float.parseFloat(contents[1].getText());
092                sampleSize = Integer.parseInt(contents[2].getText());
093                targetSize = Integer.parseInt(contents[3].getText());
094            } catch (NumberFormatException e) {
095                Scene.showErrorMessage("Format of detector configuration file is incorrect.");
096                return;
097            }
098        }
099    
100        protected void autoDetectPhase() {
101    
102            refreshDetectorParameters();
103            phase.clear();
104            samplePhase.clear();
105    
106            status = new byte[data.size()];
107    
108            if ((sampleSize<=0) || (targetSize<=0)) return;
109    
110            for (int i=0; i<data.size(); i++) {
111                if (i<sampleSize)
112                    continue;
113    
114                float rate = parse(i);
115    
116                byte currentStatus = (rate >= threshold) ? notChange : graduateChange;
117                status[i] = currentStatus;
118            }
119        }
120    
121        public Component[] createDetectorParamsControls() {
122            Component returnVal[] = new Component[8];
123    
124            for (int i=0; i<tags.length; i++) {
125                String prompt = tags[i].substring(1,tags[i].length()-1) + ": ";
126                returnVal[i*2] = new JLabel(prompt);
127                returnVal[i*2+1] = contents[i];
128                contents[i].setPreferredSize(new java.awt.Dimension(20,26));
129            }
130    
131            return returnVal;
132        }
133    
134        public void collectData(long xMappedId, long yMappedId) {
135            int x = (int)(xMappedId/interval);
136    
137            if (x >= data.size()) {
138                workingSet = new UnorderedUnlimitedSet();
139                data.add(workingSet);
140            }
141    
142            workingSet.addElement(yMappedId);
143        }
144    
145        public void saveSetting() {
146            PhaseDetectorSetting.v().save(tags,contents,configName);
147        }
148    
149        public void triggerPhases(int noiseTolerance) {
150            PhaseEntityTrigger trigger = new PhaseEntityTrigger();
151            ArrayList triggered = trigger.gatherTiggeredPhase(data, noiseTolerance);
152    
153            if (triggered.size() == 0) {
154                Scene.showErrorMessage("No phase triggered.");
155            } else
156                undoList.add(triggered);
157        }
158    
159        private float parse(int checkPoint) {
160    
161            float match = 0, average = targetSize;
162    
163            for (int i=checkPoint; i<checkPoint+targetSize; i++) {
164                float rate = 0, factor = 1;
165                if (i >= data.size()) {
166                    average = i-checkPoint+1;
167                    break;
168                }
169                current = (UnorderedUnlimitedSet)data.get(i);
170                for (int j=checkPoint-1; j>=checkPoint-sampleSize; j--) {
171                    if (j != checkPoint-1) factor = factor / 2;
172                    previous = (UnorderedUnlimitedSet)data.get(j);
173                    rate = rate + ((float)previous.intersection(current).size()/(float)previous.union(current).size())*factor;
174                }
175                match = match + rate;
176            }
177    
178            return match/average;
179        }
180    
181        protected void generatePhases() {
182            phase.clear();
183            // generate phases detected automatically.
184            autoDetectPhase();
185            int previous = status[0], noise = 0;
186            for (int i=1; i<status.length; i++) {
187                if (status[i] != previous) {
188                    noise ++;
189                    if (noise > noiseTolerance) {
190                        if (previous == graduateChange)
191                            phase.add(new Integer(i-noise));
192                        else
193                            phase.add(new Integer(i-noise+1));
194                        noise = 0;
195                        previous = status[i];
196                    }
197                } else {
198                    noise = 0;
199                }
200            }
201    
202            /*for (int i=0; i<samplePhase.size(); i++) {
203                phase.add(samplePhase.get(i));
204            }*/
205    
206            ArrayList tobeDel = new ArrayList();
207            for (int i=0; i<undoList.size(); i++) {
208                Object value = undoList.get(i);
209                if (value instanceof ArrayList) {
210                    for (int j=0; j<((ArrayList)value).size(); j++)
211                        phase.add(((ArrayList)value).get(j));
212                } else {
213                    int aPhase = ((Integer)value).intValue();
214                    if (aPhase < 0) {// a removed phase
215                        for (int j=0; j<phase.size(); j++) {
216                            if (((Integer)phase.get(j)).intValue() == (-1*aPhase)) {
217                                tobeDel.add(new Integer(j));
218                            }
219                        }
220                    } else
221                        phase.add(value);
222                }
223            }
224    
225            int counter = 0;
226            for (int i=0; i<tobeDel.size(); i++) {
227                phase.remove(((Integer)tobeDel.get(i)).intValue()-counter);
228                counter ++;
229            }
230        }
231    
232        protected void initialToolbarState() {
233            toolbarState = new PhaseDetectorToolBarState();
234            toolbarState.selectedOption = 0;
235            toolbarState.optionsControlState = new HashMap();
236        }
237    }